package com.wps.wdztv6.controller.callback;

import com.alibaba.fastjson2.JSON;
import com.wps.wdztv6.common.R;
import com.wps.wdztv6.common.ResultEnum;
import com.wps.wdztv6.config.WdztAppInfoConfig;
import com.wps.wdztv6.domain.WdztResult;
import com.wps.wdztv6.domain.edit.FileInfoCallback;
import com.wps.wdztv6.domain.edit.FileRenameCallback;
import com.wps.wdztv6.domain.edit.FileVersionCallback;
import com.wps.wdztv6.domain.edit.FileVersionsCallback;
import com.wps.wdztv6.domain.edit.OnNotifyCallback;
import com.wps.wdztv6.domain.edit.OnlineEditCallback;
import com.wps.wdztv6.domain.edit.UploadFileNewVersionCallback;
import com.wps.wdztv6.domain.edit.UserCallbackIds;
import com.wps.wdztv6.domain.edit.UserInfoCallback;
import com.wps.wdztv6.entity.ThirdFile;
import com.wps.wdztv6.entity.User;
import com.wps.wdztv6.service.FileService;
import com.wps.wdztv6.service.UserInfoService;
import com.wps.wdztv6.vo.LoggedUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 在线编辑与预览回调接口，2合一
 */
@RestController
@RequestMapping("/wdzt/v6")
@Slf4j
public class EditAndPreviewCallbackController {

    @Autowired
    private FileService fileService;

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 文件信息回调接口
     *
     * @param fileId         文件id，中台回调本接口时带来 必传
     * @param webofficeToken 启用前段jssdk鉴权后发过来，如果未开启则一般为空
     * @return 文件信息
     */
    @GetMapping("/v1/3rd/file/info")
    public Object v13rdFileInfo(
            @RequestHeader(value = "x-weboffice-file-id") String fileId,
            @RequestHeader(value = "x-wps-weboffice-token", required = false) String webofficeToken,
            @RequestParam(value = WdztAppInfoConfig.USER_TOKEN_KEY_2_W_THIRD) String userToken,
            HttpServletResponse res
    ) {
        log.info("/v1/3rd/file/info x-weboffice-file-id:{} x-wps-weboffice-token:{}", fileId, webofficeToken);
        log.info("/v1/3rd/file/info userToken:{}", userToken);

        LoggedUser userInfo = userInfoService.getUserInfo(userToken);
        userInfoService.validateUser(userInfo);

        R<ThirdFile> thirdFileR = fileService.getLatestFileByFileId(fileId);

        if (thirdFileR.getResult() != ResultEnum.SUCCESS.getCode()) {
            log.info("文件不存在:{}", fileId);
            res.setStatus(400);
            return WdztResult.failed("文件不存在存在", "请检查文件信息是否正确");
        }

        ThirdFile thirdFile = thirdFileR.getData();

        FileInfoCallback.FileMeta.UserAccessControlList userAcl = FileInfoCallback.FileMeta.UserAccessControlList.builder()
                .copy(1)
                .export(1)
                .history(1)
                .rename(1)
                .print(1)
                .build();



        FileInfoCallback.User user = FileInfoCallback.User.builder()
                // oa用户名是写死的
                .id(userInfo.getId())//
                .name(userInfo.getName())//
                .avatarUrl(userInfoService.genUserAvatarLink(userInfo.getId())) //
                .permission("write")
                .build();
        FileInfoCallback.FileMeta fileMeta = FileInfoCallback.FileMeta.builder()
                .id(fileId)
                .name(thirdFile.getName())
                .version(thirdFile.getVersion())
                .size(thirdFile.getSize())
                .userAcl(userAcl)
                .creator(userInfo.getId()) //
                .modifier(userInfo.getId()) //
                .watermark(FileInfoCallback.FileMeta.Watermark.builder()
                        .type(0)
                        .build())
                .createTime(thirdFile.getCreateTime())
                .modifyTime(thirdFile.getCreateTime())
                .downloadUrl(fileService.getDownloadUrl(fileId, thirdFile.getVersion()))
                .build();

        FileInfoCallback response = FileInfoCallback.builder()
                .user(user)
                .file(fileMeta)
                .build();
        log.info("返回信息:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 中台根据用户id请求获取用户信息回调接口
     *
     * @param fileId         文件id
     * @param webofficeToken
     * @param bodyMap        用户ids数组
     * @return 用户数组信息
     */
    @PostMapping("/v1/3rd/user/info")
    public UserInfoCallback v13rdUserInfo(
            @RequestHeader(value = "x-weboffice-file-id", required = false) String fileId,
            @RequestHeader(value = "x-wps-weboffice-token", required = false) String webofficeToken,
            @RequestParam(value = WdztAppInfoConfig.USER_TOKEN_KEY_2_W_THIRD) String userToken,
            @RequestBody(required = false) HashMap<String, List<String>> bodyMap

    ) {
        log.info("/v1/3rd/user/info userToken:{}", userToken);
        log.info("/v1/3rd/user/info ids:{} :{} {}", bodyMap, fileId, webofficeToken);
        log.info("中台根据用户id请求获取用户信息回调接口 ids:{} :{} {}", bodyMap, fileId, webofficeToken); // todo
        List<UserInfoCallback.User> users = new ArrayList<>();
        for (String id : bodyMap.get("ids")) {
            User user1 = userInfoService.selectOneById(id);
            String userName = "用户" + id;
            if (user1 != null) {
                userName = user1.getName();
            }
            UserInfoCallback.User user = UserInfoCallback.User.builder().id(id).name(userName).avatarUrl(userInfoService.genUserAvatarLink(id)).build();
            users.add(user);
        }
        UserInfoCallback response = UserInfoCallback.builder().users(users).build();
        log.info("文档中台获取用户信息回调接口返回信息:{}", JSON.toJSONString(response));
        return response;
    }


    /**
     * 服务端save回调接口，上传文件新版本
     *
     * @param fileId
     * @param webofficeToken
     * @param file
     * @return
     */
    @PostMapping("/v1/3rd/file/save")
    public UploadFileNewVersionCallback v13rdFileSave(@RequestHeader(value = "x-weboffice-file-id", required = false) String fileId,
                                                      @RequestHeader(value = "x-wps-weboffice-token", required = false) String webofficeToken,
                                                      @RequestParam(value = WdztAppInfoConfig.USER_TOKEN_KEY_2_W_THIRD) String userToken,
                                                      @RequestParam(value = "file") MultipartFile file) {
        log.info("/v1/3rd/file/save :{} {}", fileId, webofficeToken);
        UploadFileNewVersionCallback response;

        LoggedUser userInfo = userInfoService.getUserInfo(userToken);
        userInfoService.validateUser(userInfo);

        if (file != null && !file.isEmpty()) {

            R<ThirdFile> thirdFileR = fileService.saveFileNewVersion(fileId, file);
            if (thirdFileR.getResult() == ResultEnum.SUCCESS.getCode()) {
                UploadFileNewVersionCallback.File newVersionFile = UploadFileNewVersionCallback.File.builder()
                        .id(fileId)
                        .name(thirdFileR.getData().getName())
                        .size(thirdFileR.getData().getSize())
                        .version(thirdFileR.getData().getVersion())
                        .downloadUrl(fileService.getDownloadUrl(fileId, thirdFileR.getData().getVersion()))
                        .build();
                response = UploadFileNewVersionCallback.builder().file(newVersionFile).build();
            } else {
                response = UploadFileNewVersionCallback.builder().build();
            }
        } else {
            response = UploadFileNewVersionCallback.builder().build();
        }
        log.info("文件保存新版本:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 文件重命名  FileRenameCallback没用上
     *
     * @param fileId
     * @param webofficeToken
     * @param mapName
     * @return
     */
    @PutMapping("/v1/3rd/file/rename")
    @ResponseBody
    public FileRenameCallback v13rdFileRename(
            @RequestHeader(value = "x-weboffice-file-id", required = false) String fileId,
            @RequestHeader(value = "x-wps-weboffice-token", required = false) String webofficeToken,
            @RequestParam(value = WdztAppInfoConfig.USER_TOKEN_KEY_2_W_THIRD) String userToken,
            @RequestBody Map<String, String> mapName) {

        //测试发现 webofficeToken 空的
        log.info("/v1/3rd/file/rename :{} >>>{}", fileId, webofficeToken);
        //RequestBody 包含了  file_id, name , attrs
        log.info("/v1/3rd/file/rename__RequestBody :{}", mapName);


        LoggedUser userInfo = userInfoService.getUserInfo(userToken);
        userInfoService.validateUser(userInfo);

        R<ThirdFile> RenameThirdFile = fileService.fileRename(fileId, mapName.get("name"));
        log.info("文件重命名结果:{}", RenameThirdFile);

        FileRenameCallback response = FileRenameCallback.builder().build();
        log.info("返回信息:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 通知此文件目前有哪些人正在协作
     *
     * @param fileId
     * @param webofficeToken
     * @param ids
     * @return
     */
    @PostMapping("/v1/3rd/file/online")
    public OnlineEditCallback v13rdFileOnlie(
            @RequestHeader(value = "x-weboffice-file-id", required = false) String fileId,
            @RequestHeader(value = "x-wps-weboffice-token", required = false) String webofficeToken,
            @RequestBody(required = false) UserCallbackIds ids) {
        log.info("/v1/3rd/file/online :{} {}", fileId, webofficeToken);
        log.info("文件:{} 在线人数:{}", fileId, JSON.toJSONString(ids));

        return OnlineEditCallback.builder().build();
    }


    /**
     * 7. 获取特定版本的文件信息
     * 适用版本>=v6.0.2206.20220629
     * 在历史版本预览和回滚历史版本的时候，获取特定版本文档的文件信息。
     *
     * @param fileId
     * @param webofficeToken
     * @param version
     * @return
     */
    @GetMapping("/v1/3rd/file/version/{version}")
    public FileVersionCallback v13rdFileVersion(
            @RequestHeader(value = "x-weboffice-file-id", required = false) String fileId,
            @RequestHeader(value = "x-wps-weboffice-token", required = false) String webofficeToken,
            @PathVariable("version") Integer version,
            @RequestParam(value = WdztAppInfoConfig.USER_TOKEN_KEY_2_W_THIRD) String userToken
    ) {
        log.info("/v1/3rd/file/version/ userToken:{}", userToken);
        log.info("/v1/3rd/file/version/{} :{} {}", version, fileId, webofficeToken);
        R<ThirdFile> versionFileR = fileService.getFileByVersion(fileId, version);

        LoggedUser userInfo = userInfoService.getUserInfo(userToken);
        userInfoService.validateUser(userInfo);

        FileVersionCallback.File versionFile = FileVersionCallback.File.builder()
                .id(fileId)
                .name(versionFileR.getData().getName())
                .version(version)
                .creator(userInfo.getId())//
                .modifier(userInfo.getId())//
                .modifyTime(versionFileR.getData().getUpdateTime())
                .createTime(versionFileR.getData().getCreateTime())
                .size(versionFileR.getData().getSize())
                .downloadUrl(fileService.getDownloadUrl(fileId, version))
                .build();
        FileVersionCallback response = FileVersionCallback.builder().file(versionFile).build();
        log.info("返回特定版本历史信息:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 获取所有历史版本文件信息
     *
     * @param fileId
     * @param webofficeToken
     * @return
     */
    @PostMapping("/v1/3rd/file/history")
    public FileVersionsCallback v13rdFileHistory(
            @RequestHeader(value = "x-weboffice-file-id", required = false) String fileId,
            @RequestHeader(value = "x-wps-weboffice-token", required = false) String webofficeToken,
            @RequestParam(value = WdztAppInfoConfig.USER_TOKEN_KEY_2_W_THIRD) String userToken
    ) {

        log.info("/v1/3rd/file/history :{} {}", fileId, webofficeToken);
        R<List<ThirdFile>> versionsFileR = fileService.getFileHistory(fileId);

        List<FileVersionsCallback.File> fileList = new ArrayList<>();
        LoggedUser userInfo = userInfoService.getUserInfo(userToken);
        userInfoService.validateUser(userInfo);

        for (ThirdFile thirdFile : versionsFileR.getData()) {
            fileList.add(
                    FileVersionsCallback.File.builder()
                            .id(fileId)
                            .name(thirdFile.getName())
                            .createTime(thirdFile.getCreateTime())
                            .size(thirdFile.getSize())
                            //版本
                            .version(thirdFile.getVersion())
                            .downloadUrl(fileService.getDownloadUrl(fileId, thirdFile.getVersion()))
                            .modifier(FileVersionsCallback.File.User.builder()
                                    .id(userInfo.getId())//
                                    .name(userInfo.getName())//
                                    .avatarUrl(userInfoService.genUserAvatarLink(userInfo.getId()))//
                                    .build()
                            )
                            .creator(FileVersionsCallback.File.User.builder()
                                    .id(userInfo.getId())//
                                    .name(userInfo.getName())//
                                    .avatarUrl(userInfoService.genUserAvatarLink(userInfo.getId()))//
                                    .build())
                            .modifyTime(thirdFile.getCreateTime())
                            .build()
            );
        }
        FileVersionsCallback response = FileVersionsCallback.builder().files(fileList).build();
        log.info("返回历史版本列表信息:{}", JSON.toJSONString(response));
        return response;
    }

    /**
     * 打开或关闭文件时，WPS 会回调一些通知，目前有 7 类回调通知（详情查看下文的请求示例）
     * <p>
     * 注：
     * 1.某些错误会导致不触发打开文件总数的回调通知。
     * 2.接口只能用来运维和运营统计，请不要依赖该接口做计费、版本保存等需求
     *
     * @param fileId
     * @param webofficeToken
     * @param body
     */
    @PostMapping("/v1/3rd/onnotify")
    public void v13rdOnNotify(@RequestHeader(value = "x-weboffice-file-id", required = false) String fileId,
                              @RequestHeader(value = "x-wps-weboffice-token", required = false) String webofficeToken,
                              @RequestBody(required = false) OnNotifyCallback body) {

        log.info("/v1/3rd/onnotify 结果:{}", body);
    }
}
